package com.nervenets.general.filter;

import com.nervenets.general.config.ApplicationProperties;
import com.nervenets.general.utils.AESUtils;
import com.nervenets.general.wapper.NerveNetsHttpServletRequestWrapper;
import lombok.AllArgsConstructor;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * 2020/6/23 17:49 created by Joe
 **/
@AllArgsConstructor
public class NerveNetsRequestWrapperFilter implements Filter {
    private final ApplicationProperties applicationProperties;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest servletRequest = (HttpServletRequest) request;

        final String requestURI = servletRequest.getRequestURI();
        if (null != applicationProperties.getInvalidUrlContents()) {
            for (String urlFilter : applicationProperties.getInvalidUrlContents()) {
                if (requestURI.contains(urlFilter)) {
                    response.setContentType("text/html");
                    response.setCharacterEncoding("UTF-8");
                    response.getWriter().write("Oh! This url is invalid.");
                    return;
                }
            }
        }

        if ("application/x-www-form-urlencoded".equals(servletRequest.getHeader("content-type"))) {
            filterChain.doFilter(servletRequest, response);
        } else {
            //防止后续参数能正常获取，需要先读取一次...
            servletRequest.getParameterMap();
            servletRequest.getParameterNames();

            NerveNetsHttpServletRequestWrapper wrapper = new NerveNetsHttpServletRequestWrapper((HttpServletRequest) request);
            //如果请求body为加密状态，解密之...
            if (applicationProperties.isRequestEncrypt() && !wrapper.isEmptyBody()) {
                wrapper.setBodyCopier(Objects.requireNonNull(AESUtils.decryptData(wrapper.getBody())).getBytes(StandardCharsets.UTF_8));
            }
            filterChain.doFilter(wrapper, response);
        }
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
